<template>
  <div class="drawer" v-loading="props.loading || loadingInfo">
    <el-drawer ref="drawerEl" v-model="visible" :show-close="false" :close-on-click-modal="false" lock-scroll destroy-on-close v-bind="$attrs">
      <template #header>
        <div class="flex-row-center-between title-drawer pd10">
          <div class="bold">{{ props.title }}</div>
          <el-button type="danger" @click="handleCloseByValidate"> 关闭 </el-button>
        </div>
      </template>
      <el-form ref="formEl" :model="props.formData" v-bind="props.formAttrs">
        <slot></slot>
      </el-form>

      <template #footer v-if="props.showFooter">
        <div>
          <el-button @click="handleCloseByValidate" :loading="props.loading || loadingInfo">取消</el-button>
          <el-button type="primary" @click="handleConfirm" :loading="props.loading || loadingInfo">保存</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script lang="ts" setup>
  import { ref } from 'vue'
  import { ElDrawer } from 'element-plus'
  import request from '@/service'
  import type { FormInstance } from 'element-plus'
  import type { ValidateFn } from '../index'
  import { Ui } from '@/utils'

  interface IEmits {
    (e: 'submit-success'): void
    (e: 'before-submit', data: any, fn: ValidateFn): void
    (e: 'refactor-params', data: any): void
  }

  const emits = defineEmits<IEmits>()

  const props = defineProps({
    loading: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '标题'
    },
    showFooter: {
      type: Boolean,
      default: true
    },
    formData: {
      type: Object,
      default: () => ({})
    },
    formAttrs: {
      type: Object,
      default: () => ({})
    },
    api: {
      type: String,
      default: ''
    },
    apiMethod: {
      type: String,
      default: 'post'
    }
  })

  const formEl = ref<FormInstance>()
  const drawerEl = ref<InstanceType<typeof ElDrawer>>()

  const visible = ref(false)
  const loadingInfo = ref(false)

  /**----------------------------methods----------------------------------------------------------------------- */

  const handleConfirm = () => {
    let continueSubmit = true
    let tipMsg = ''
    emits('before-submit', props.formData, (v: boolean, msg: string) => {
      continueSubmit = v
      tipMsg = msg
    })

    if (!continueSubmit) return Ui.useMessage('warning', tipMsg)

    formEl.value?.validate(v => {
      if (!v) return
      emits('refactor-params', props.formData)
      loadingInfo.value = true
      request[props.apiMethod as 'post' | 'put'](props.api, props.formData)
        .then(res => {
          if (res.code !== 0) return Ui.useMessage('error', res.msg)

          Ui.useMessage('success', res.msg)

          emits('submit-success')

          handleClose()
        })
        .finally(() => (loadingInfo.value = false))
    })
  }

  const handleOpen = () => {
    visible.value = true
  }

  /**直接关闭 */
  const handleClose = () => {
    visible.value = false
  }

  /**关闭前可做校验 */
  const handleCloseByValidate = () => {
    drawerEl.value?.handleClose()
  }

  /**----------------------------lifecycle----------------------------------------------------------------------- */

  defineExpose({
    handleOpen,
    handleClose,
    handleCloseByValidate
  })
</script>

<style scoped lang="less">
  .drawer {
    .title-drawer {
      border-bottom: 2px solid #ebeef5;
    }
    :deep(.el-drawer .el-drawer__header) {
      color: #000;
      padding: 0;
      margin: 0;
      background: #f2f3f5;
    }
  }
</style>
